home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Games / UniversalHIDModuleTest / TestHIDprobe.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  16.4 KB  |  502 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        TestHIDprobe.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1998 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                xxx put dri here xxx
  13.  
  14.         Other Contact:        xxx put other contact here xxx
  15.  
  16.         Technology:            xxx put technology here xxx
  17.  
  18.     Writers:
  19.  
  20.         (BWS)    Brent Schorsch
  21.  
  22.     Change History (most recent first):
  23.  
  24.         <0*>     5/18/98    BWS        stolen from USBProber
  25. */
  26.  
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include <errors.h>
  30. #include <USB.h>
  31.  
  32. /*    HID Constants - Spec 1.0 */
  33.  
  34. #define    UnpackReportSize(packedByte)    ((packedByte) & 0x03)
  35. #define    UnpackReportType(packedByte)    (((packedByte) & 0x0C) >> 2)
  36. #define    UnpackReportTag(packedByte)        (((packedByte) & 0xF0) >> 4)
  37.  
  38. enum
  39. {
  40.     kReport_TypeMain            = 0,
  41.     kReport_TypeGlobal            = 1,
  42.     kReport_TypeLocal            = 2,
  43.     kReport_TypeReserved        = 3,
  44.     
  45.     kReport_TagLongItem            = 0x0F,
  46.     
  47.     // main items
  48.     kReport_TagInput            = 0x08,
  49.     kReport_TagOutput            = 0x09,
  50.     kReport_TagFeature            = 0x0B,
  51.     kReport_TagCollection        = 0x0A,
  52.     kReport_TagEndCollection    = 0x0C,
  53.     
  54.     // global items
  55.     kReport_TagUsagePage        = 0x00,
  56.     kReport_TagLogicalMin        = 0x01,
  57.     kReport_TagLogicalMax        = 0x02,
  58.     kReport_TagPhysicalMin        = 0x03,
  59.     kReport_TagPhysicalMax        = 0x04,
  60.     kReport_TagUnitExponent        = 0x05,
  61.     kReport_TagUnit                = 0x06,
  62.     kReport_TagReportSize        = 0x07,
  63.     kReport_TagReportID            = 0x08,
  64.     kReport_TagReportCount        = 0x09,
  65.     kReport_TagPush                = 0x0A,
  66.     kReport_TagPop                = 0x0B,
  67.  
  68.     // local items
  69.     kReport_TagUsage            = 0x00,
  70.     kReport_TagUsageMin            = 0x01,
  71.     kReport_TagUsageMax            = 0x02,
  72.     kReport_TagDesignatorIndex    = 0x03,
  73.     kReport_TagDesignatorMin    = 0x04,
  74.     kReport_TagDesignatorMax    = 0x05,
  75.     kReport_TagStringIndex        = 0x07,
  76.     kReport_TagStringMin        = 0x08,
  77.     kReport_TagStringMax        = 0x09,
  78.     kReport_TagSetDelimiter        = 0x0A
  79. };
  80.  
  81. // Collection constants
  82. enum
  83. {
  84.     kCollection_Physical        = 0x00,
  85.     kCollection_Application        = 0x01,
  86.     kCollection_Logical            = 0x02
  87. };
  88.  
  89. // I/O constants (used for Input/Output/Feature tags)
  90. enum
  91. {
  92.     kIO_Data_or_Constant                = 0x0001,
  93.     kIO_Array_or_Variable                = 0x0002,
  94.     kIO_Absolute_or_Relative            = 0x0004,
  95.     kIO_NoWrap_or_Wrap                    = 0x0008,
  96.     kIO_Linear_or_NonLinear                = 0x0010,
  97.     kIO_PreferredState_or_NoPreferred    = 0x0020,
  98.     kIO_NoNullPosition_or_NullState        = 0x0040,
  99.     kIO_NonVolatile_or_Volatile            = 0x0080,        // reserved for Input
  100.     kIO_BitField_or_BufferedBytes        = 0x0100
  101. };
  102.  
  103. // Usage pages from HID Usage Tables spec 1.0
  104. enum
  105. {
  106.     kUsage_PageGenericDesktop        = 0x01,
  107.     kUsage_PageSimulationControls    = 0x02,
  108.     kUsage_PageVRControls            = 0x03,
  109.     kUsage_PageSportControls        = 0x04,
  110.     kUsage_PageGameControls            = 0x05,
  111.     kUsage_PageKeyboard                = 0x07,
  112.     kUsage_PageLED                    = 0x08,
  113.     kUsage_PageButton                = 0x09,
  114.     kUsage_PageOrdinal                = 0x0A,
  115.     kUsage_PageTelephonyDevice        = 0x0B,
  116.     kUsage_PageConsumer                = 0x0C,
  117.     kUsage_PageDigitizers            = 0x0D,
  118.     kUsage_PageUnicode                = 0x10,
  119.     kUsage_PageAlphanumericDisplay    = 0x14
  120. };
  121.  
  122. // Usage constants for Generic Desktop page (01) from HID Usage Tables spec 1.0
  123. enum
  124. {
  125.     kUsage_01_Pointer        = 0x01,
  126.     kUsage_01_Mouse            = 0x02,
  127.     kUsage_01_Joystick        = 0x04,
  128.     kUsage_01_GamePad        = 0x05,
  129.     kUsage_01_Keyboard        = 0x06,
  130.     kUsage_01_Keypad        = 0x07,
  131.     
  132.     kUsage_01_X                = 0x30,
  133.     kUsage_01_Y                = 0x31,
  134.     kUsage_01_Z                = 0x32,
  135.     kUsage_01_Rx            = 0x33,
  136.     kUsage_01_Ry            = 0x34,
  137.     kUsage_01_Rz            = 0x35,
  138.     kUsage_01_Slider        = 0x36,
  139.     kUsage_01_Dial            = 0x37,
  140.     kUsage_01_Wheel            = 0x38,
  141.     kUsage_01_HatSwitch        = 0x39,
  142.     kUsage_01_CountedBuffer    = 0x3A,
  143.     kUsage_01_ByteCount        = 0x3B,
  144.     kUsage_01_MotionWakeup    = 0x3C,
  145.     
  146.     kUsage_01_Vx            = 0x40,
  147.     kUsage_01_Vy            = 0x41,
  148.     kUsage_01_Vz            = 0x42,
  149.     kUsage_01_Vbrx            = 0x43,
  150.     kUsage_01_Vbry            = 0x44,
  151.     kUsage_01_Vbrz            = 0x45,
  152.     kUsage_01_Vno            = 0x46,
  153.     
  154.     kUsage_01_SystemControl        = 0x80,
  155.     kUsage_01_SystemPowerDown     = 0x81,
  156.     kUsage_01_SystemSleep         = 0x82,
  157.     kUsage_01_SystemWakeup        = 0x83,
  158.     kUsage_01_SystemContextMenu = 0x84,
  159.     kUsage_01_SystemMainMenu    = 0x85,
  160.     kUsage_01_SystemAppMenu        = 0x86,
  161.     kUsage_01_SystemMenuHelp    = 0x87,
  162.     kUsage_01_SystemMenuExit    = 0x88,
  163.     kUsage_01_SystemMenuSelect    = 0x89,
  164.     kUsage_01_SystemMenuRight    = 0x8A,
  165.     kUsage_01_SystemMenuLeft    = 0x8B,
  166.     kUsage_01_SystemMenuUp        = 0x8C,
  167.     kUsage_01_SystemMenuDown    = 0x8D
  168. };
  169.  
  170. /*    end HID Constants Spec 1.0     */
  171.  
  172. void PrintHIDReport(UInt8 * reportDesc, UInt32 length);
  173.  
  174. void PrintHIDReport(UInt8 * reportDesc, UInt32 length)
  175. {
  176.     UInt8 *         currByte;
  177.     UInt8 *            end;
  178.     UInt8            size, type, tag;
  179.     UInt32            usagePage = 0;
  180.     UInt32            value;
  181.     SInt32            svalue;
  182.     unsigned char    buf[256], tempbuf[256];
  183.     int                i, k, indentLevel;
  184.     Boolean            datahandled;
  185.     Boolean            usagesigned;
  186.     
  187.     end = reportDesc + length;
  188.     
  189.     printf("Report Descriptor\n");
  190.     printf("0x%x (%d) Bytes\n", length, length);
  191.     
  192.     k= 0;
  193.     buf[0] = 0;
  194.     
  195.     currByte = reportDesc;
  196.     for(i=0; i < length + 3; i++)
  197.     {
  198.         if (!(k%16))
  199.         {
  200.             sprintf((char *)buf, "%04X:", k);
  201.         };
  202.         sprintf((char *)tempbuf, "%02X ", *(currByte++));
  203.         strcat((char *)buf, (char *)tempbuf);
  204.         
  205.         k++;
  206.         if (!(k%16))
  207.         {
  208.             printf("%s\n", (char *)buf);
  209.         };
  210.     };
  211.     if ((k%16))
  212.         printf("%s\n", (char *)buf);
  213.         
  214.     buf[0] = 0;
  215.     indentLevel = 0;
  216.     
  217.     while (reportDesc < end)
  218.     {
  219.         size = UnpackReportSize(*reportDesc);
  220.         if (size == 3) size = 4;    // 0 == 0 bytes, 1 == 1 bytes, 2 == 2 bytes, but 3 == 4 bytes
  221.         
  222.         type = UnpackReportType(*reportDesc);
  223.         tag = UnpackReportTag(*reportDesc);
  224.         reportDesc++;
  225.         
  226.         if (tag == kReport_TagLongItem)
  227.         {
  228.             size = *reportDesc++;
  229.             tag = *reportDesc++;
  230.         }
  231.         
  232.         
  233.         // if we're small enough, load the value into a register (byte swaping)
  234.         if (size <= 4)
  235.         {
  236.             value = 0;
  237.             for (i = 0; i < size; i++)
  238.                 value += (*(reportDesc++)) << (i * 8);
  239.             
  240.             svalue = 0;
  241.             switch (size)
  242.             {
  243.                 case 1: svalue = (SInt8) value; break;
  244.                 case 2: svalue = (SInt16) value; break;
  245.                 
  246.                 // if the top bit is set, then sign extend it and fall thru to 32bit case
  247.                 case 3: if (value & 0x00800000) value |= 0xFF000000; // no break
  248.                 case 4: svalue = (SInt32) value; break;
  249.             }
  250.         }
  251.  
  252.         // indent this line
  253.         buf[0] = 0;
  254.         for (i = 0; i < indentLevel; i++)
  255.             strcat((char *)buf, "  ");
  256.         
  257.         
  258.         // get the name of this tag, and do any specific data handling
  259.         datahandled = false;
  260.         switch (type)
  261.         {
  262.             case kReport_TypeMain:
  263.             switch (tag)
  264.             {
  265.                 case kReport_TagInput:
  266.                 case kReport_TagOutput:
  267.                 case kReport_TagFeature:
  268.                     switch (tag)
  269.                     {
  270.                         case kReport_TagInput: strcat((char *)buf, "Input "); break;
  271.                         case kReport_TagOutput: strcat((char *)buf, "Output "); break;
  272.                         case kReport_TagFeature: strcat((char *)buf, "Feature "); break;
  273.                     }
  274.  
  275.                     strcat((char *)buf, (char *)"(");
  276.                     if (value & kIO_Data_or_Constant) strcat((char *)buf, "Constant");
  277.                     else strcat((char *)buf, "Data");
  278.                     
  279.                     if (value & kIO_Array_or_Variable) strcat((char *)buf, ", Variable");
  280.                     else strcat((char *)buf, ", Array");
  281.  
  282.                     if (value & kIO_Absolute_or_Relative) strcat((char *)buf, ", Relative");
  283.                     else strcat((char *)buf, ", Absolute");
  284.  
  285.                     if (value & kIO_NoWrap_or_Wrap) strcat((char *)buf, ", Null State");
  286.                     
  287.                     if (value & kIO_Linear_or_NonLinear) strcat((char *)buf, ", Nonlinear");
  288.                     
  289.                     if (value & kIO_PreferredState_or_NoPreferred) strcat((char *)buf, ", No Preferred");
  290.                     
  291.                     if (value & kIO_NoNullPosition_or_NullState) strcat((char *)buf, ", Null State");
  292.                     
  293.                     if (tag != kReport_TagInput)
  294.                         if (value & kIO_NonVolatile_or_Volatile) strcat((char *)buf, ", Volatile");
  295.                         else strcat((char *)buf, ", Non-volatile");
  296.  
  297.                     if (value & kIO_BitField_or_BufferedBytes) strcat((char *)buf, ", Buffered bytes");
  298.                     strcat((char *)buf, (char *)")");
  299.                     
  300.                     tempbuf[0] = 0;    // we don't want to add this again outside the switch
  301.                     datahandled = true;
  302.                     break;
  303.                     
  304.                 
  305.                 case kReport_TagCollection:
  306.                     indentLevel++; 
  307.                     
  308.                     sprintf((char *)tempbuf, "Collection "); 
  309.                     strcat((char *)buf, (char *)tempbuf);
  310.  
  311.                     strcat((char *)buf, (char *)"(");
  312.                     switch (value)
  313.                     {
  314.                         case kCollection_Physical: sprintf((char *)tempbuf, "Physical"); break;
  315.                         case kCollection_Application: sprintf((char *)tempbuf, "Application"); break;
  316.                         case kCollection_Logical: sprintf((char *)tempbuf, "Logical"); break;
  317.                     }
  318.                     strcat((char *)buf, (char *)tempbuf);
  319.                     strcat((char *)buf, (char *)")");
  320.                     
  321.                     tempbuf[0] = 0;    // we don't want to add this again outside the switch
  322.                     datahandled = true;
  323.                     break;
  324.  
  325.                 case kReport_TagEndCollection: 
  326.                     // recalc indentation, since we want this line to start earlier
  327.                     indentLevel--;
  328.                     buf[0] = 0;
  329.                     for (i = 0; i < indentLevel; i++)
  330.                         strcat((char *)buf, "  ");
  331.                     
  332.                     sprintf((char *)tempbuf, "End Collection "); 
  333.                     break;
  334.             }
  335.             break;
  336.             
  337.             case kReport_TypeGlobal:
  338.             switch (tag)
  339.             {
  340.                 case kReport_TagUsagePage:
  341.                     sprintf((char *)tempbuf, "Usage Page ");
  342.                     strcat((char *)buf, (char *)tempbuf);
  343.  
  344.                     usagesigned = true;
  345.                     usagePage = value;
  346.                     strcat((char *)buf, (char *)"(");
  347.                     switch (usagePage)
  348.                     {
  349.                         case kUsage_PageGenericDesktop: sprintf((char *)tempbuf, "Generic Desktop"); break;
  350.                         case kUsage_PageSimulationControls: sprintf((char *)tempbuf, "Simulation Controls"); break;
  351.                         case kUsage_PageVRControls: sprintf((char *)tempbuf, "VR Controls"); break;
  352.                         case kUsage_PageSportControls: sprintf((char *)tempbuf, "Sports Controls"); break;
  353.                         case kUsage_PageGameControls: sprintf((char *)tempbuf, "Game Controls"); break;
  354.                         case kUsage_PageKeyboard: 
  355.                                 sprintf((char *)tempbuf, "Keyboard/Keypad"); 
  356.                                 usagesigned = false;
  357.                                 break;
  358.                                 
  359.                         case kUsage_PageLED: sprintf((char *)tempbuf, "LED"); break;
  360.                         case kUsage_PageButton: sprintf((char *)tempbuf, "Button"); break;
  361.                         case kUsage_PageOrdinal: sprintf((char *)tempbuf, "Ordinal"); break;
  362.                         case kUsage_PageTelephonyDevice: sprintf((char *)tempbuf, "Telephany Device"); break;
  363.                         case kUsage_PageConsumer: sprintf((char *)tempbuf, "Consumer"); break;
  364.                         case kUsage_PageDigitizers: sprintf((char *)tempbuf, "Digitizer"); break;
  365.                         case kUsage_PageUnicode: sprintf((char *)tempbuf, "Unicode"); break;
  366.                         case kUsage_PageAlphanumericDisplay: sprintf((char *)tempbuf, "Alphanumeric Display"); break;
  367.                         
  368.                         default: sprintf((char *)tempbuf, "%d", usagePage); break;
  369.                     }
  370.                     strcat((char *)buf, (char *)tempbuf);
  371.                     strcat((char *)buf, (char *)")");
  372.                     tempbuf[0] = 0;    // we don't want to add this again outside the switch
  373.                     datahandled = true;
  374.                     break;
  375.                 
  376.                 case kReport_TagLogicalMin: sprintf((char *)tempbuf,      "Logical Minimum.... "); break;
  377.                 case kReport_TagLogicalMax: sprintf((char *)tempbuf,      "Logical Maximum.... "); break;
  378.                 case kReport_TagPhysicalMin: sprintf((char *)tempbuf,     "Physical Minimum... "); break;
  379.                 case kReport_TagPhysicalMax: sprintf((char *)tempbuf,     "Physical Maximum... "); break;
  380.                 case kReport_TagUnitExponent: sprintf((char *)tempbuf,    "Unit Exponent...... "); break;
  381.                 case kReport_TagUnit: sprintf((char *)tempbuf,            "Unit............... "); break;
  382.                 case kReport_TagReportSize: sprintf((char *)tempbuf,      "Report Size........ "); break;
  383.                 case kReport_TagReportID: sprintf((char *)tempbuf,        "ReportID........... "); break;
  384.                 case kReport_TagReportCount: sprintf((char *)tempbuf,     "Report Count....... "); break;
  385.                 case kReport_TagPush: sprintf((char *)tempbuf,            "Push............... "); break;
  386.                 case kReport_TagPop: sprintf((char *)tempbuf,             "Pop................ "); break;
  387.             }
  388.             break;
  389.             
  390.             case kReport_TypeLocal:
  391.             switch (tag)
  392.             {
  393.                 case kReport_TagUsage:
  394.                     sprintf((char *)tempbuf, "Usage ");
  395.                     strcat((char *)buf, (char *)tempbuf);
  396.                     strcat((char *)buf, (char *)"(");
  397.                     switch (value)
  398.                     {
  399.                         case kUsage_01_Pointer: sprintf((char *)tempbuf, "Pointer"); break;
  400.                         case kUsage_01_Mouse: sprintf((char *)tempbuf, "Mouse"); break;
  401.                         case kUsage_01_Joystick: sprintf((char *)tempbuf, "Joystick"); break;
  402.                         case kUsage_01_GamePad: sprintf((char *)tempbuf, "GamePad"); break;
  403.                         case kUsage_01_Keyboard: sprintf((char *)tempbuf, "Keyboard"); break;
  404.                         case kUsage_01_Keypad: sprintf((char *)tempbuf, "Keypad"); break;
  405.  
  406.                         case kUsage_01_X: sprintf((char *)tempbuf, "X"); break;
  407.                         case kUsage_01_Y: sprintf((char *)tempbuf, "Y"); break;
  408.                         case kUsage_01_Z: sprintf((char *)tempbuf, "Z"); break;
  409.                         case kUsage_01_Rx: sprintf((char *)tempbuf, "Rx"); break;
  410.                         case kUsage_01_Ry: sprintf((char *)tempbuf, "Ry"); break;
  411.                         case kUsage_01_Rz: sprintf((char *)tempbuf, "Rz"); break;
  412.                         case kUsage_01_Slider: sprintf((char *)tempbuf, "Slider"); break;
  413.                         case kUsage_01_Dial: sprintf((char *)tempbuf, "Dial"); break;
  414.                         case kUsage_01_Wheel: sprintf((char *)tempbuf, "Wheel"); break;
  415.                         case kUsage_01_HatSwitch: sprintf((char *)tempbuf, "Hat Switch"); break;
  416.                         case kUsage_01_CountedBuffer: sprintf((char *)tempbuf, "Counted Buffer"); break;
  417.                         case kUsage_01_ByteCount: sprintf((char *)tempbuf, "Byte Count"); break;
  418.                         case kUsage_01_MotionWakeup: sprintf((char *)tempbuf, "Motion Wakeup"); break;
  419.  
  420.                         case kUsage_01_Vx: sprintf((char *)tempbuf, "Vx"); break;
  421.                         case kUsage_01_Vy: sprintf((char *)tempbuf, "Vy"); break;
  422.                         case kUsage_01_Vz: sprintf((char *)tempbuf, "Vz"); break;
  423.                         case kUsage_01_Vbrx: sprintf((char *)tempbuf, "Vbrx"); break;
  424.                         case kUsage_01_Vbry: sprintf((char *)tempbuf, "Vbry"); break;
  425.                         case kUsage_01_Vbrz: sprintf((char *)tempbuf, "Vbrz"); break;
  426.                         case kUsage_01_Vno: sprintf((char *)tempbuf, "Vno"); break;
  427.  
  428.                         case kUsage_01_SystemControl: sprintf((char *)tempbuf, "System Control"); break;
  429.                         case kUsage_01_SystemPowerDown: sprintf((char *)tempbuf, "System Power Down"); break;
  430.                         case kUsage_01_SystemSleep: sprintf((char *)tempbuf, "System Sleep"); break;
  431.                         case kUsage_01_SystemWakeup: sprintf((char *)tempbuf, "System Wakeup"); break;
  432.                         case kUsage_01_SystemContextMenu: sprintf((char *)tempbuf, "System Context Menu"); break;
  433.                         case kUsage_01_SystemMainMenu: sprintf((char *)tempbuf, "System Main Menu"); break;
  434.                         case kUsage_01_SystemAppMenu: sprintf((char *)tempbuf, "System App Menu"); break;
  435.                         case kUsage_01_SystemMenuHelp: sprintf((char *)tempbuf, "System Menu Help"); break;
  436.                         case kUsage_01_SystemMenuExit: sprintf((char *)tempbuf, "System Menu Exit"); break;
  437.                         case kUsage_01_SystemMenuSelect: sprintf((char *)tempbuf, "System Menu Select"); break;
  438.                         case kUsage_01_SystemMenuRight: sprintf((char *)tempbuf, "System Menu Right"); break;
  439.                         case kUsage_01_SystemMenuLeft: sprintf((char *)tempbuf, "System Menu Left"); break;
  440.                         case kUsage_01_SystemMenuUp: sprintf((char *)tempbuf, "System Menu Up"); break;
  441.                         case kUsage_01_SystemMenuDown: sprintf((char *)tempbuf, "System Menu Down"); break;
  442.                         
  443.                         default: sprintf((char *)tempbuf, "%d", value); break;
  444.                     }
  445.                     strcat((char *)buf, (char *)tempbuf);
  446.                     strcat((char *)buf, (char *)")");
  447.                     tempbuf[0] = 0;    // we don't want to add this again outside the switch
  448.                     datahandled = true;
  449.                     break;
  450.                 
  451.                 case kReport_TagUsageMin: sprintf((char *)tempbuf,        "Usage Minimum...... "); break;
  452.                 case kReport_TagUsageMax: sprintf((char *)tempbuf,        "Usage Maximum...... "); break;
  453.                 case kReport_TagDesignatorIndex: sprintf((char *)tempbuf, "Designator Index... "); break;
  454.                 case kReport_TagDesignatorMin: sprintf((char *)tempbuf,   "Designator Minumum. "); break;
  455.                 case kReport_TagDesignatorMax: sprintf((char *)tempbuf,   "Designator Maximum. "); break;
  456.                 case kReport_TagStringIndex: sprintf((char *)tempbuf,     "String Index....... "); break;
  457.                 case kReport_TagStringMin: sprintf((char *)tempbuf,       "String Minimum..... "); break;
  458.                 case kReport_TagStringMax: sprintf((char *)tempbuf,       "String Maximum..... "); break;
  459.                 case kReport_TagSetDelimiter: sprintf((char *)tempbuf,    "Set Delimiter...... "); break;
  460.             }
  461.             break;
  462.             
  463.             case kReport_TypeReserved:
  464.             sprintf((char *)tempbuf, "Reserved "); break;
  465.             break;
  466.         }
  467.         
  468.         // actually put in the data from the switch -- why not just strcat there??
  469.         strcat((char *)buf, (char *)tempbuf);
  470.         
  471.         // if we didn't handle the data before, print in generic fashion
  472.         if (!datahandled && size)
  473.         {
  474.             strcat((char *)buf, (char *)"(");
  475.             if (size <= 4)
  476.             {
  477.                 if (usagesigned)
  478.                 {
  479.                     sprintf((char *)tempbuf, "%ld", (SInt32)svalue);
  480.                 }
  481.                 else
  482.                 {
  483.                     sprintf((char *)tempbuf, "%lu", (UInt32)value);
  484.                 }
  485.                 strcat((char *)buf, (char *)tempbuf);
  486.             }
  487.             else
  488.                 for (i = 0; i < size; i++)
  489.                 {
  490.                     sprintf((char *)tempbuf, "%02X ", *(reportDesc++));
  491.                     strcat((char *)buf, (char *)tempbuf);
  492.                 }
  493.             strcat((char *)buf, (char *)") ");
  494.         }
  495.         
  496.         // finally add the info
  497. //        printf("ITEM (%s)\n", (char *) tempbuf);
  498.         printf("%s\n", (char *) buf);
  499.     }
  500. }
  501.  
  502.